package com.lipaluma.parser.marshalling;

import java.util.ArrayList;
import java.util.List;

import com.lipaluma.io.Row;
import com.lipaluma.io.SourceWriter;

public class OneToManyMarshallerColumnStrategy implements OneToManyMarshallerStrategy {

	@Override
	public void createOneToManyRows(SourceWriter fw, ObjectMarshalled objectMarshalled, Row row) {
		ArrayList<Row> rows = new ArrayList<Row>();
		rows.add(row);
		createRecursivelyOneToManyRows(fw, objectMarshalled, rows);
	}
	
	private void createRecursivelyOneToManyRows(SourceWriter fw, ObjectMarshalled objectMarshalled, List<Row> rows) {
		for (List<ObjectMarshalled> oneToManyFieldExploded : objectMarshalled.getOneToManyFieldsMarshalled()) {
			List<List<Row>> listOfRowsToWork = new ArrayList<List<Row>>();
			listOfRowsToWork.add(rows);
			for(int i=0; i<oneToManyFieldExploded.size() - 1; i++)
				listOfRowsToWork.add(duplicateRows(fw, rows));
			for (int i=0; i<oneToManyFieldExploded.size(); i++) {
				List<Row> rowsToWork = listOfRowsToWork.get(i);
				ObjectMarshalled singleObject = oneToManyFieldExploded.get(i);
				for (Row row : rowsToWork) {
					for(FieldMarshalled fieldMarshalled : singleObject.getFieldsMarshalled())
						row.writeValue(fieldMarshalled.getValue(), fieldMarshalled.getMapping());
				}
				createRecursivelyOneToManyRows(fw, singleObject, rowsToWork);
				if(i > 0)
					rows.addAll(rowsToWork);
			}
		}

	}

	private List<Row> duplicateRows(SourceWriter fw, List<Row> rows) {
		List<Row> result = new ArrayList<Row>();
		for (Row row : rows) {
			result.add(fw.duplicateRow(row));
		}
		return result;
	}
}
